package handler

import (
	"db"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
	"util"
)

const (
	pwd_salt = "a8&a"
	view_dir = "/home/rui/go_project/filestore_server/static/"
)

//用户注册
func SignupHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		data, err := ioutil.ReadFile(view_dir + "view/signup.html")
		if err != nil {
			fmt.Printf("open html err:%s", err.Error())
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.Write(data)
		return
	}

	r.ParseForm()
	username := r.Form.Get("username")
	password := r.Form.Get("password")

	if len(username) < 3 || len(password) < 5 {
		w.Write([]byte("invalid parameter"))
		return
	}
	enc_passwd := util.Sha1([]byte(password + pwd_salt))
	signup := db.UserSignup(username, enc_passwd)
	if signup {
		w.Write([]byte("SUCCESS"))
	} else {
		w.Write([]byte("FAILED"))
	}
}

// 用户登录接口
func SignInHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		data, err := ioutil.ReadFile(view_dir + "view/signin.html")
		if err != nil {
			fmt.Printf("open html err:%s", err.Error())
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.Write(data)
		return
	}

	r.ParseForm()
	username := r.Form.Get("username")
	password := r.Form.Get("password")

	if len(username) < 3 || len(password) < 5 {
		w.Write([]byte("invalid parameter"))
		return
	}
	enc_passwd := util.Sha1([]byte(password + pwd_salt))
	//1.验证是否登录
	signup := db.UserSignIn(username, enc_passwd)
	if !signup {
		w.Write([]byte("FAILED"))
		return
	}
	//2.生成token
	token := GenToken(username)
	updateToken := db.UpdateToken(username, token)
	if !updateToken {
		w.Write([]byte("FAILED"))
		return
	}
	//3.重定向到首页
	resp := util.RespMsg{
		Code: 0,
		Msg:  "OK",
		Data: struct {
			Location string
			Username string
			Token    string
		}{
			Location: "http://" + r.Host + "/static/view/home.html",
			Username: username,
			Token:    token,
		},
	}
	w.Write(resp.JSONBytes())
}

// 生成token信息
func GenToken(username string) string {
	// 40位字符:md5(username+timestamp+token_salt)+timestamp[:8]
	ts := fmt.Sprintf("%x", time.Now().Unix())
	tokenPrefix := util.MD5([]byte(username + ts + "_tokensalt"))
	return tokenPrefix + ts[:8]
}

//获取用户信息
func UserInfoHandler(w http.ResponseWriter, r *http.Request) {
	// 1.解析请求
	r.ParseForm()
	username := r.Form.Get("username")
	// 3.查询用户信息
	userinfo, err := db.GetUserInfo(username)
	if err != nil {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	// 4.组装返回信息
	resp := util.RespMsg{
		Code: 0,
		Msg:  "ok",
		Data: userinfo,
	}
	w.Write(resp.JSONBytes())
}

//验证token
func IsTokenValid(token string, username string) bool {
	if len(token) != 40 {
		return false
	}
	// TODO: 判断token的时效性，是否过期
	// example，假设token的有效期为1天   (根据同学们反馈完善, 相对于视频有所更新)
	tokenTS := token[len(token)-8:]
	if util.Hex2Dec(tokenTS) < time.Now().Unix()-86400 {
		return false
	}
	// TODO: 从数据库表tbl_user_token查询username对应的token信息
	if db.GetUserToken(username) != token {
		return false
	}
	return true
}
